using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WorkflowActions;

namespace DP.Sharepoint.Workflow
{
    /// <summary>
    /// sends a mail message using mail server configured in sharepoint, also attaches a file retrieved using HTTP request
    /// </summary>
    public class SendMailWHttpFileAttachment2 : Activity
    {
        #region Dependency Properties

        public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context",
                                                                                         typeof (WorkflowContext),
                                                                                         typeof (
                                                                                             SendMailWHttpFileAttachment2
                                                                                             ));

        public static DependencyProperty AttachmentFileNameProperty = DependencyProperty.Register("AttachmentFileName",
                                                                                                  typeof (string),
                                                                                                  typeof (
                                                                                                      SendMailWHttpFileAttachment2
                                                                                                      ));

        public static DependencyProperty AttachmentWebUrlProperty = DependencyProperty.Register("AttachmentWebUrl",
                                                                                                typeof (string),
                                                                                                typeof (
                                                                                                    SendMailWHttpFileAttachment2
                                                                                                    ));

        public static DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof (string),
                                                                                    typeof (SendMailWHttpFileAttachment2
                                                                                        ));

        public static DependencyProperty ImpersonateSystemAccountProperty =
            DependencyProperty.Register("ImpersonateSystemAccount", typeof (string),
                                        typeof (SendMailWHttpFileAttachment2));

        public static DependencyProperty IsMessageUrgentProperty = DependencyProperty.Register("IsMessageUrgent",
                                                                                               typeof (string),
                                                                                               typeof (
                                                                                                   SendMailWHttpFileAttachment2
                                                                                                   ));

        public static DependencyProperty RecipientCCProperty = DependencyProperty.Register("RecipientCC",
                                                                                           typeof (ArrayList),
                                                                                           typeof (
                                                                                               SendMailWHttpFileAttachment2
                                                                                               ));


        public static DependencyProperty RecipientFromProperty = DependencyProperty.Register("RecipientFrom",
                                                                                             typeof (string),
                                                                                             typeof (
                                                                                                 SendMailWHttpFileAttachment2
                                                                                                 ));

        public static DependencyProperty RecipientTOProperty = DependencyProperty.Register("RecipientTO",
                                                                                           typeof (ArrayList),
                                                                                           typeof (
                                                                                               SendMailWHttpFileAttachment2
                                                                                               ));

        public static DependencyProperty SubjectProperty = DependencyProperty.Register("Subject", typeof (string),
                                                                                       typeof (
                                                                                           SendMailWHttpFileAttachment2));

        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public WorkflowContext __Context
        {
            get { return ((WorkflowContext) (base.GetValue(__ContextProperty))); }
            set { base.SetValue(__ContextProperty, value); }
        }

        [Description("Sender address. If this value is not specified, default sharepoint sender address will be used")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string RecipientFrom
        {
            get { return ((string) (base.GetValue(RecipientFromProperty))); }
            set { base.SetValue(RecipientFromProperty, value); }
        }

        [Description("Recipient address")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public ArrayList RecipientTO
        {
            get { return ((ArrayList) (base.GetValue(RecipientTOProperty))); }
            set { base.SetValue(RecipientTOProperty, value); }
        }

        [Description("Carbon copy recipient")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public ArrayList RecipientCC
        {
            get { return ((ArrayList) (base.GetValue(RecipientCCProperty))); }
            set { base.SetValue(RecipientCCProperty, value); }
        }


        [Description(
            "url of the file to be downloaded and attached to the email. Both http and https requests are supported")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string AttachmentWebUrl
        {
            get { return ((string) (base.GetValue(AttachmentWebUrlProperty))); }
            set { base.SetValue(AttachmentWebUrlProperty, value); }
        }

        [Description(
            "Name of the attachment. This is very important. Extention of the file will determine which program will open the attachment."
            )]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string AttachmentFileName
        {
            get { return ((string) (base.GetValue(AttachmentFileNameProperty))); }
            set { base.SetValue(AttachmentFileNameProperty, value); }
        }

        [Description("")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Subject
        {
            get { return ((string) (base.GetValue(SubjectProperty))); }
            set { base.SetValue(SubjectProperty, value); }
        }

        [Description("HTML body of the message")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string Body
        {
            get { return ((string) (base.GetValue(BodyProperty))); }
            set { base.SetValue(BodyProperty, value); }
        }

        [Description("Determines whether message is priority is high")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string IsMessageUrgent
        {
            get { return ((string) (base.GetValue(IsMessageUrgentProperty))); }
            set { base.SetValue(IsMessageUrgentProperty, value); }
        }

        [Description(
            "Determines whether the file retrieval should run under user context or should impersonate sharepoint account"
            )]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string ImpersonateSystemAccount
        {
            get { return ((string) (base.GetValue(ImpersonateSystemAccountProperty))); }
            set { base.SetValue(ImpersonateSystemAccountProperty, value); }
        }

        #endregion

        private void InitializeComponent()
        {
            // 
            // SendMailWAttachment
            // 
            Name = "SendMailWHttpFileAttachment2";
        }


        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            try
            {
                Stream myContent = null;

                string url = Common.ProcessStringField(executionContext, AttachmentWebUrl);


                if (bool.Parse(ImpersonateSystemAccount))
                {
                    //get file using Sharepoint application pool credentials
                    //this is useful if user does not have permissions to the file, but shaprepoint application pool account does
                    SPSecurity.RunWithElevatedPrivileges(
                        delegate { myContent = Common.GetHttpFileUsingDefaultCredentials(url); });
                }
                else
                    myContent = Common.GetHttpFileUsingDefaultCredentials(url);


                //need administrative credentials to get to Web Application Properties info
                SPSecurity.RunWithElevatedPrivileges(delegate
                                                         {
                                                             using (SPSite mySite = new SPSite(__Context.Site.ID))
                                                             {
                                                                 string to = RecipientTO == null
                                                                                 ? string.Empty
                                                                                 : Common.ParseSendTo(__Context,
                                                                                                      RecipientTO);

                                                                 string cc = RecipientCC == null
                                                                                 ? string.Empty
                                                                                 : Common.ParseSendTo(__Context,
                                                                                                      RecipientCC);

                                                                 to = Common.ProcessStringField(executionContext, to);

                                                                 cc = Common.ProcessStringField(executionContext, cc);

                                                                 string from =
                                                                     Common.ProcessStringField(executionContext,
                                                                                               RecipientFrom);

                                                                 string subject =
                                                                     Common.ProcessStringField(executionContext, Subject);

                                                                 string body =
                                                                     Common.ProcessStringField(executionContext, Body);

                                                                 string attachName =
                                                                     Common.ProcessStringField(executionContext,
                                                                                               AttachmentFileName);

                                                                 Common.SendMailWithAttachment(mySite, from, to, cc,
                                                                                               subject, body, myContent,
                                                                                               attachName,
                                                                                               bool.Parse(
                                                                                                   IsMessageUrgent));
                                                             }
                                                         });
            }
            catch (Exception e)
            {
                Common.LogExceptionToWorkflowHistory(e, executionContext, WorkflowInstanceId);

                throw;
            }

            return base.Execute(executionContext);
        }
    }
}